/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.UIManager;

import java.sql.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import oracle.sdoapi.OraSpatialManager;
import oracle.sdoapi.geom.*;
import oracle.sdoapi.adapter.*;
import oracle.sdoapi.sref.*;
import oracle.sql.STRUCT;

/**
 *
 * @author zhouzhao
 */
public class Spatial extends JFrame implements ActionListener, 
        ItemListener, ListSelectionListener{
    
    private ArrayList<Restaurant> restArray;
    private ArrayList<Photo> photoArray;
    private ArrayList<MyPoint> pointArray;
    
    private Connection mainConnection = null;
    private Statement mainStatement = null;
    private ResultSet mainResultSet = null;

//    public imagePanel mapImage;
    private ButtonGroup groupRB;
    private int [] feature = new int [2];
    private int queryIndex = 1;
    private int x = 0, y = 0, k = 1;
    
    private DefaultListModel listModel;
    
    private String restName = "ihop";
    private int xPhoto = 0, yPhoto = 0;
    private String foodType = "fast food";
    private int xRest = 0, yRest = 0;
    

    /**
     * Creates new form Spatial
     */
    public Spatial() {
        initComponents();
    }
    
    public void init(){
        
        feature[0] = 1;
        feature[1] = 0;
        restArray = new ArrayList<Restaurant>();
        photoArray = new ArrayList<Photo>();
        pointArray = new ArrayList<MyPoint>();
        
        pointArray.add(new MyPoint(1, 1));
        pointArray.add(new MyPoint(599, 1));
        pointArray.add(new MyPoint(599, 499));
        pointArray.add(new MyPoint(1, 499));
        
        //specify radio buttons
        nearRB.setMnemonic(KeyEvent.VK_N);
        nearRB.setActionCommand("near");
        nearRB.setSelected(true);
        
        rangeRB.setMnemonic(KeyEvent.VK_R);
        rangeRB.setActionCommand("range");
        
        matchRB.setMnemonic(KeyEvent.VK_M);
        matchRB.setActionCommand("match");
        
        relevantRB.setMnemonic(KeyEvent.VK_L);
        relevantRB.setActionCommand("relevant");
        
        //group the radio buttons
        groupRB = new ButtonGroup();
        groupRB.add(nearRB);
        groupRB.add(rangeRB);
        groupRB.add(matchRB);
        groupRB.add(relevantRB);
        
        //register action listener
        nearRB.addActionListener(this);
        rangeRB.addActionListener(this);
        matchRB.addActionListener(this);
        relevantRB.addActionListener(this);
        
        //register item listener
        restCB.setMnemonic(KeyEvent.VK_E);
        restCB.setSelected(true);
        photoCB.setMnemonic(KeyEvent.VK_P);
        restCB.addItemListener(this);
        photoCB.addItemListener(this);
        
        xValue.addActionListener(this);
        xValue.setActionCommand("xvalue");
        
        yValue.addActionListener(this);
        yValue.setActionCommand("yvalue");
        
        kValue.addActionListener(this);
        kValue.setActionCommand("kvalue");
        
        listModel = new DefaultListModel();
        rpList.setModel(listModel);
        rpList.addListSelectionListener(this);
        
        connectDB();
    }
    
    @Override
    public void actionPerformed(ActionEvent event){
        String command = event.getActionCommand();
        if(command.equals("near")){
            queryIndex = 1;
        }else if(command.equals("range")){
            queryIndex = 2;
        }else if(command.equals("match")){
            queryIndex = 3;
        }else if(command.equals("relevant")){
            queryIndex = 4;
        }else if(command.equals("xvalue")){
            x = Integer.parseInt(xValue.getText());
            xValue.selectAll();
        }else if(command.equals("yvalue")){
            y = Integer.parseInt(yValue.getText());
            yValue.selectAll();
        }else if(command.equals("kvalue")){
            k = Integer.parseInt(kValue.getText());
            kValue.selectAll();
        }
        
        System.out.println("query = " + queryIndex + " x = " + x + " y = " + y + 
                " k = " + k);
    }

    @Override
    public void itemStateChanged(ItemEvent event){
        Object source = event.getItemSelectable();
        
        if(source == restCB){
            if(event.getStateChange() == ItemEvent.SELECTED){
                feature[0] = 1;
            }else if(event.getStateChange() == ItemEvent.DESELECTED){
                feature[0] = 0;
            }
        }else if(source == photoCB){
            if(event.getStateChange() == ItemEvent.SELECTED){
                feature[1] = 1;
            }else if(event.getStateChange() == ItemEvent.DESELECTED){
                feature[1] = 0;
            }            
        }
        
        System.out.println(feature[0] + " " + feature[1]);
    }
    
    @Override
    public void valueChanged(ListSelectionEvent event){
        int index;
        if(event.getValueIsAdjusting() == false){
            if((index = rpList.getSelectedIndex()) != -1){
                if(index < restArray.size()){
                    infoArea.setText(restArray.get(index).restName + " " + restArray.get(index).foodType
                        + " " + restArray.get(index).phoneNum);
                    foodType = restArray.get(index).foodType;
                    xRest = (int)restArray.get(index).xDim;
                    yRest = (int)restArray.get(index).yDim;
                    
                }else{
                    infoArea.setText(photoArray.get(index - restArray.size()).photoName + " " + photoArray.get(index - restArray.size()).restName);
                    restName = photoArray.get(index - restArray.size()).restName;
                    xPhoto = (int)photoArray.get(index - restArray.size()).xDim;
                    yPhoto = (int)photoArray.get(index - restArray.size()).yDim;
                    detailPanel.imageName = photoArray.get(index - restArray.size()).photoName;
                    detailPanel.repaint();
                }
            }
        }
    }
    
    public static ImageIcon createImageIcon(String path, String description){
        URL imgURL = Spatial.class.getResource(path);
        if(imgURL != null){
            return new ImageIcon(imgURL, description);
        }else{
            System.err.println("error: could not find file " + path);
            return null;
        }
    }
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        clearForm = new javax.swing.JButton();
        submitQuery = new javax.swing.JButton();
        restCB = new javax.swing.JCheckBox();
        photoCB = new javax.swing.JCheckBox();
        jLabel1 = new javax.swing.JLabel();
        xValue = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        yValue = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        kValue = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        prompt = new javax.swing.JTextArea();
        jPanel1 = new javax.swing.JPanel();
        nearRB = new javax.swing.JRadioButton();
        rangeRB = new javax.swing.JRadioButton();
        matchRB = new javax.swing.JRadioButton();
        relevantRB = new javax.swing.JRadioButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        infoArea = new javax.swing.JTextArea();
        jScrollPane3 = new javax.swing.JScrollPane();
        rpList = new javax.swing.JList();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        mapPanel = new gui.imagePanel();
        detailPanel = new gui.photoPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Zhou Zhao 8710598310");
        setPreferredSize(new java.awt.Dimension(1000, 800));

        clearForm.setText("Clear");
        clearForm.setToolTipText("clear the form");
        clearForm.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearFormActionPerformed(evt);
            }
        });

        submitQuery.setText("Submit Query");
        submitQuery.setToolTipText("submit query to DB");
        submitQuery.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                submitQueryActionPerformed(evt);
            }
        });

        restCB.setText("Restaurants");
        restCB.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                restCBActionPerformed(evt);
            }
        });

        photoCB.setText("Photos");

        jLabel1.setText("Active Features");

        xValue.setColumns(5);
        xValue.setText("0");

        jLabel2.setText("X coordinates");

        jLabel3.setText("Y coordinates");

        yValue.setColumns(5);
        yValue.setText("0");

        jLabel4.setText("Input K");

        kValue.setColumns(5);
        kValue.setText("1");

        prompt.setColumns(20);
        prompt.setEditable(false);
        prompt.setLineWrap(true);
        prompt.setRows(5);
        jScrollPane1.setViewportView(prompt);

        jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        jPanel1.setAlignmentY(5.0F);

        nearRB.setText("Nearest Neighbor");

        rangeRB.setText("Range");

        matchRB.setText("Matching Rest");

        relevantRB.setText("Relevant Photo");

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                        .add(nearRB, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(rangeRB, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .add(matchRB)
                    .add(relevantRB))
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .add(nearRB)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(rangeRB)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(matchRB)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(relevantRB))
        );

        infoArea.setColumns(20);
        infoArea.setEditable(false);
        infoArea.setLineWrap(true);
        infoArea.setRows(5);
        jScrollPane2.setViewportView(infoArea);

        rpList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jScrollPane3.setViewportView(rpList);

        jLabel5.setText("Query statement");

        jLabel6.setText("Result set list");

        jLabel7.setText("Information of tuple");

        detailPanel.setPreferredSize(new java.awt.Dimension(300, 300));

        org.jdesktop.layout.GroupLayout detailPanelLayout = new org.jdesktop.layout.GroupLayout(detailPanel);
        detailPanel.setLayout(detailPanelLayout);
        detailPanelLayout.setHorizontalGroup(
            detailPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 300, Short.MAX_VALUE)
        );
        detailPanelLayout.setVerticalGroup(
            detailPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 300, Short.MAX_VALUE)
        );

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createSequentialGroup()
                        .add(mapPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(18, 18, 18)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(jScrollPane2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 258, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .add(jLabel7)
                            .add(layout.createSequentialGroup()
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(jScrollPane3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 207, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                    .add(jLabel6))
                                .add(18, 18, 18)
                                .add(detailPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))))
                    .add(layout.createSequentialGroup()
                        .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                            .add(layout.createSequentialGroup()
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                                    .add(layout.createSequentialGroup()
                                        .add(jLabel1)
                                        .add(9, 9, 9))
                                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                        .add(restCB)
                                        .add(photoCB)))
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(jLabel2)
                                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                        .add(jLabel4)
                                        .add(jLabel3)))
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(yValue, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                    .add(xValue, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                    .add(kValue, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                            .add(layout.createSequentialGroup()
                                .add(clearForm)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(submitQuery)))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(jLabel5)
                            .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 392, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap(183, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createSequentialGroup()
                        .add(mapPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(jLabel5)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED))
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                        .add(109, 109, 109)
                        .add(jLabel7)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jScrollPane2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 76, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                            .add(layout.createSequentialGroup()
                                .add(jLabel6)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                                .add(jScrollPane3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 275, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                            .add(detailPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                        .add(91, 91, 91)))
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                        .add(jLabel1)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(restCB)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(photoCB))
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                            .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .add(layout.createSequentialGroup()
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                                    .add(clearForm)
                                    .add(submitQuery))
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                                    .add(xValue, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                    .add(jLabel2))
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                                    .add(jLabel3)
                                    .add(yValue, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                                    .add(jLabel4)
                                    .add(kValue, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))))
                        .add(8, 8, 8))
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void clearFormActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearFormActionPerformed
        // TODO add your handling code here:
        nearRB.setSelected(true);
        rangeRB.setSelected(false);
        matchRB.setSelected(false);
        relevantRB.setSelected(false);
        queryIndex = 1;
        
        restCB.setSelected(true);
        photoCB.setSelected(false);
        feature[0] = 1;
        feature[1] = 0;
        
        xValue.setText("0");
        yValue.setText("0");
        kValue.setText("1");
        x = 0;
        y = 0;
        k = 1;
        
        prompt.setText("");
        infoArea.setText("");
        listModel.removeAllElements();
    }//GEN-LAST:event_clearFormActionPerformed

    private void submitQueryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_submitQueryActionPerformed
        // TODO add your handling code here:
        x = mapPanel.x;
        xValue.setText(x + "");
        y = mapPanel.y;
        yValue.setText(y + "");
        
        k = Integer.parseInt(kValue.getText());
        restArray.clear();
        photoArray.clear();
        
        switch (queryIndex){
            case 1:{
                if(feature[0] == 1 && feature[1] == 0){
                    findRestDistance();
                    storeRestPoints();
                    populateList();
                }else if(feature[0] == 0 && feature[1] == 1){
                    findPhotoDistance();
                    storePhotoPoints();
                    populateList();
                }else if(feature[0] == 1 && feature[1] == 1){
                    findRestDistance();
                    storeRestPoints();
                    findPhotoDistance();
                    storePhotoPoints();
                    populateList();
                }
                break;
            }
            case 2:{
                findRestPhotoRange();
                break;
            }
            case 3:{
                findMatchRest();
                storeRestPoints();
                populateList();
                break;
            }
            case 4:{
                findRelevantPhoto();
                storePhotoPoints();
                populateList();
                break;
            }
            default: System.err.println("error: query index is NOT valid");
        }
        
        mapPanel.photoDrawArray = photoArray;
        mapPanel.restDrawArray = restArray;
        mapPanel.repaint();
    }//GEN-LAST:event_submitQueryActionPerformed

    private void restCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_restCBActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_restCBActionPerformed

    public void findRestDistance(){
        
        try {
            
            String restInsertTarget = "insert into restaurants values (" + 100 + ", " 
                        + "'" + "target" + "'" + ", " + "sdo_geometry(2001, null, sdo_point_type(" + x + ", " + y + ", " + "null), null, null), " + "'" + "none" + "'" + ", " + "'" + "none" + "'" + ")";
            mainStatement.executeUpdate(restInsertTarget);
            System.out.println("rest target point is inserted");
            
            String restNear = "select * from (select R.* from restaurants R, (select R2.* from restaurants R1, restaurants R2 where R1.restID = 100 and R2.restID in (select R3.restID from restaurants R3 where R3.restID <> 100) order by sdo_geom.sdo_distance(R1.restPoint, R2.restPoint, 0.005) asc) points where R.restID = points.restID) points2 where rownum <= " + k;
//            System.out.println(restNear);
            mainResultSet =  mainStatement.executeQuery(restNear);
            prompt.setText(restNear + "\n");
            
        } catch (Exception e) {
            System.out.println("error: " + e.toString());
        }
    }
    
    public void findPhotoDistance(){
        
        try {
            String photoInsertTarget = "insert into photos values (" + 100 + ", " + "'" + "target" + "'" +
                        ", " + "sdo_geometry(2001, null, sdo_point_type(" + x + ", " + y + ", " + "null), null, null), " + "'" +
                        "none" + "'" + ")";
            mainStatement.executeUpdate(photoInsertTarget);
            System.out.println("photo target point is inserted");
            
            String photoNear = "select * from (select R.* from photos R, (select R2.* from photos R1, photos R2 where R1.photoID = 100 and R2.photoID in (select R3.photoID from photos R3 where R3.photoID <> 100) order by sdo_geom.sdo_distance(R1.photoPoint, R2.photoPoint, 0.005) asc) points where R.photoID = points.photoID) points2 where rownum <= " + k;
            mainResultSet = mainStatement.executeQuery(photoNear);
            prompt.setText(photoNear + "\n");
            
        } catch (Exception e) {
            System.out.println("error: " + e.toString());
        }
    }
    
    public void findMatchRest(){
        
        try {
            String restInsertTarget = "insert into restaurants values (" + 100 + ", " 
                        + "'" + "target" + "'" + ", " + "sdo_geometry(2001, null, sdo_point_type(" + xPhoto + ", " + yPhoto + ", " + "null), null, null), " + "'" + "none" + "'" + ", " + "'" + "none" + "'" + ")";
            mainStatement.executeUpdate(restInsertTarget);
            System.out.println("photo point is inserted in rest");
            
            String matchRest = "select R.* from restaurants R, (select R2.* from restaurants R1, restaurants R2 where R1.restID = 100 and R2.restID in (select R3.restID from restaurants R3 where R3.restID <> 100 and R3.restName = '" + restName + "') order by sdo_geom.sdo_distance(R1.restPoint, R2.restPoint, 0.005) asc) points where R.restID = points.restID";
            mainResultSet = mainStatement.executeQuery(matchRest);
            prompt.setText(matchRest + "\n");
            
        } catch (Exception e) {
            System.out.println("error: " + e.toString());
        }
    }
    
    public void findRelevantPhoto(){
        
        try {
            String photoInsertTarget = "insert into photos values (" + 100 + ", " + "'" + "target" + "'" +
                        ", " + "sdo_geometry(2001, null, sdo_point_type(" + xRest + ", " + yRest + ", " + "null), null, null), " + "'" +
                        "none" + "'" + ")";
            mainStatement.executeUpdate(photoInsertTarget);
            System.out.println("rest point is inserted in photo");
            
            String relevantPhoto = "select * from (select P2.* from photos R, photos P2 where R.photoID = 100 and P2.photoID in (select P1.photoID from restaurants R1, photos P1, tags T1 where T1.feature = R1.foodType and T1.photoID = P1.photoID and R1.foodType = '" + foodType + "') order by sdo_geom.sdo_distance(R.photoPoint, P2.photoPoint, 0.005) asc) photos where rownum <= " + k;
            mainResultSet = mainStatement.executeQuery(relevantPhoto);
            prompt.setText(relevantPhoto + "\n");
            
        } catch (Exception e) {
            System.out.println("error: " + e.toString());
        }
    }
    
    public void findRestPhotoRange(){
        
        try {
            String region = "";
            System.out.println("point: " + pointArray.size());
            for(int i=0; i < pointArray.size(); i++){
                region = region.concat(pointArray.get(i).x + "," + pointArray.get(i).y + ", ");
            }
            region = region.concat(pointArray.get(0).x + "," + pointArray.get(0).y);
            System.out.println(region);
            
            String mapInsertTarget = "insert into maps values (100, sdo_geometry(2003, null, null, sdo_elem_info_array(1, 1003, 1), sdo_ordinate_array(" + region + ")))";
            mainStatement.executeUpdate(mapInsertTarget);
            System.out.println("region is inserted in map");
            
            String photoRange = "select P2.* from photos P2, (select P.photoID, sdo_geom.relate(M.region, 'anyinteract', P.photoPoint, 0.005) cc from maps M, photos P where M.mapID = 100 and P.photoID in (select P1.photoID from photos P1)) photos where photos.cc = 'TRUE' and P2.photoID = photos.photoID";
            mainResultSet = mainStatement.executeQuery(photoRange);
            prompt.setText(photoRange + "\n");
            
            storePhotoPoints();
            
            String restRange = "select P2.* from restaurants P2, (select P.restID, sdo_geom.relate(M.region, 'anyinteract', P.restPoint, 0.005) cc from maps M, restaurants P where M.mapID = 100 and P.restID in (select P1.restID from restaurants P1)) rests where rests.cc = 'TRUE' and P2.restID = rests.restID";
            mainResultSet = mainStatement.executeQuery(restRange);
            prompt.append(restRange + "\n");
            
            storeRestPoints();
            populateList();
            
            mainStatement.executeUpdate("delete from maps where maps.mapID = 100");
            System.out.println("target region is deleted");
            
        } catch (Exception e) {
            System.out.println("error: " + e.toString());
        }
    }
    
    public void populateList(){
        
        try {
            listModel.removeAllElements();
            for(int i = 0; i < restArray.size(); i++){
                listModel.addElement("restID: " + restArray.get(i).restID + " restName: " + restArray.get(i).restName);
            }
            for(int j = 0; j < photoArray.size(); j++){
                listModel.addElement("photoID: " + photoArray.get(j).photoID + " photoName: " + photoArray.get(j).photoName);
            }
        } catch (Exception e) {
            System.out.println("error: " + e.toString());
        }

    }
    
    public void storeRestPoints(){
        
        STRUCT obj;
        Geometry geom;
        
        try {
            
            ResultSetMetaData meta = mainResultSet.getMetaData();
            System.out.println("show all spatial rest points");
            GeometryAdapter sdoAdapter = OraSpatialManager.getGeometryAdapter("SDO", "9", STRUCT.class, null, null, mainConnection);
            
            int restCount = 0;
            while (mainResultSet.next()) {
                restArray.add(new Restaurant());
                
                System.out.println("restCount = " + restCount);
                restArray.get(restCount).restID = mainResultSet.getInt(1);
                System.out.println("id = " + restArray.get(restCount).restID);
                restArray.get(restCount).restName = mainResultSet.getString(2);
                
                obj = (STRUCT)mainResultSet.getObject(3);
                geom = sdoAdapter.importGeometry(obj);
                
                if(geom instanceof Point){
                    Point point = (Point)geom;
                    System.out.println("x = " + point.getX() + " y = " + point.getY());
                    restArray.get(restCount).xDim = point.getX();
                    restArray.get(restCount).yDim = point.getY();
//                    prompt.append(restArray.get(restCount).restID + "x = " + point.getX() + " y = " + point.getY() + "\n");
                }
                
                restArray.get(restCount).foodType = mainResultSet.getString(4);
                restArray.get(restCount).phoneNum = mainResultSet.getString(5);
                restCount++;
                
//                for(int i = 0; i < k; i++) System.out.println(restArray[i].restID + " " + restArray[i].restName + " " + restArray[i].foodType
//                        + " " + restArray[i].phoneNum);
            }
            
            String restRemoveTarget = "delete from restaurants R where R.restID = 100";
            mainStatement.executeUpdate(restRemoveTarget);
            System.out.println("target rest point is deleted");
            
        } catch (Exception e) {
            System.out.println("error: " + e.toString());
        }
    }
    
    public void storePhotoPoints(){
        
        STRUCT obj;
        Geometry geom;
        
        try {
            
            ResultSetMetaData meta = mainResultSet.getMetaData();
            System.out.println("show all spatial photo points");
            GeometryAdapter sdoAdapter = OraSpatialManager.getGeometryAdapter("SDO", "9", STRUCT.class, null, null, mainConnection);
            
            int photoCount = 0;
            while (mainResultSet.next()) {                
                photoArray.add(new Photo());
                
                photoArray.get(photoCount).photoID = mainResultSet.getInt(1);
                photoArray.get(photoCount).photoName = mainResultSet.getString(2);
                
                obj = (STRUCT)mainResultSet.getObject(3);
                geom = sdoAdapter.importGeometry(obj);
                
                if(geom instanceof Point){
                    Point point = (Point)geom;
                    System.out.println("x = " + point.getX() + " y = " + point.getY());
                    photoArray.get(photoCount).xDim = point.getX();
                    photoArray.get(photoCount).yDim = point.getY();
                }
                
                photoArray.get(photoCount).restName = mainResultSet.getString(4);
                photoCount++;
            }
            
            String photoRemoveTarget = "delete from photos P where P.photoID = 100";
            mainStatement.executeUpdate(photoRemoveTarget);
            System.out.println("target photo point is deleted");            
            
        } catch (Exception e) {
            System.out.println("error: " + e.toString());
        }
    }
    
    public final void connectDB(){
        
        try {
            //loading oracle driver
            System.out.println("looking for jdbc-odbc driver");
            DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
            System.out.println("jdbc-odbc driver is loaded");
            
            String url = "jdbc:oracle:thin:@128.125.225.230:1521:orcl";
            String userName = "zhouzhao";
            String password = "zz831022";
            
            System.out.println("connecting to db ...");
            mainConnection = DriverManager.getConnection(url, userName, password);
            System.out.println("db is connected");
            
//            mainStatement = mainConnection.createStatement();
//            secondStatement = mainConnection.prepareStatement("insert into users values (?, ?, ?, ?, ?)");
            mainStatement = mainConnection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
//            fourthStatement = mainConnection.prepareStatement("insert into cola_markets values (?, ?, ?)");
            
        } catch (Exception e) {
            System.out.println("error: " + e.toString());
//            e.printStackTrace();
            System.exit(-1);
        }
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
     
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Spatial.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Spatial.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Spatial.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Spatial.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
//                UIManager.getLookAndFeelDefaults().put("Panel.background", Color.RED);
                
                Spatial frame = new Spatial();
                frame.init();
                frame.setSize(800, 800);
                
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton clearForm;
    private gui.photoPanel detailPanel;
    private javax.swing.JTextArea infoArea;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JTextField kValue;
    private gui.imagePanel mapPanel;
    private javax.swing.JRadioButton matchRB;
    private javax.swing.JRadioButton nearRB;
    private javax.swing.JCheckBox photoCB;
    private javax.swing.JTextArea prompt;
    private javax.swing.JRadioButton rangeRB;
    private javax.swing.JRadioButton relevantRB;
    private javax.swing.JCheckBox restCB;
    private javax.swing.JList rpList;
    private javax.swing.JButton submitQuery;
    private javax.swing.JTextField xValue;
    private javax.swing.JTextField yValue;
    // End of variables declaration//GEN-END:variables
}
